/**
 * 通用统计
 */
import React from 'react'
import {exportFile, fetchPost} from '../../utils/request'
import {Table, Form, DatePicker, Button, Select, Radio, message} from 'antd'

const {RangePicker} = DatePicker
const FormItem = Form.Item
const {Option} = Select;
import moment from 'moment'
import XLSX from 'xlsx'

class ReportCommon extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      exportAllow: props.exportAllow,
      buttonHidden: false,
      keyList: [],
      data: [],
      columns: [],
      params: {},
      lastParams: {},
      queryKey: null,
      loading: false,
      name: ''
    }
  }

  componentDidMount() {
    this.componentWillReceiveProps(this.props);
  }

  componentWillReceiveProps(props) {
    if (Object.keys(props.params).length == 0) {
      return;
    }

    if (this.Compare(props.params, this.state.params)) {
      return;
    }

    this.setState({
      params: props.params,
      queryKey: props.queryKey,
      name: props.name
    }, () => {
      this.getData(props.params, props.queryKey)
    })
  }

  Compare(objA, objB) {
    if (!this.isObj(objA) || !this.isObj(objB)) return false; //判断类型是否正确
    if (this.getLength(objA) != this.getLength(objB)) return false; //判断长度是否一致
    return this.CompareObj(objA, objB, true);//默认为true
  }

  CompareObj(objA, objB, flag) {
    for (var key in objA) {
      if (!flag) //跳出整个循环
        break;
      if (!objB.hasOwnProperty(key)) {
        flag = false;
        break;
      }
      if (!this.isArray(objA[key])) { //子级不是数组时,比较属性值
        if (objB[key] != objA[key]) {
          flag = false;
          break;
        }
      } else {
        if (!this.isArray(objB[key])) {
          flag = false;
          break;
        }
        var oA = objA[key], oB = objB[key];
        if (oA.length != oB.length) {
          flag = false;
          break;
        }
        for (var k in oA) {
          if (!flag) //这里跳出循环是为了不让递归继续
            break;
          flag = this.CompareObj(oA[k], oB[k], flag);
        }
      }
    }
    return flag;
  }

  isObj(object) {
    return object && typeof (object) == 'object' && Object.prototype.toString.call(object).toLowerCase() == "[object object]";
  }

  isArray(object) {
    return object && typeof (object) == 'object' && object.constructor == Array;
  }

  getLength(object) {
    var count = 0;
    for (var i in object) count++;
    return count;
  }

  getData(params, queryKey) {
    this.setState({
      loading: true
    })

    fetchPost(`/bizStats/general/query`, {...params, queryKey}).then(json => {

      if (json && json.data != null && JSON.stringify(json.data) != '{}' && json.code === 0) {
        let keyList = json.data[`${queryKey}KeyList`]
        let data = json.data[queryKey]
        console.log(keyList);
        let columns = []
        if (keyList != null && keyList.length > 0) {
          keyList.map(item => {
            columns.push({
              title: item,
              dataIndex: item,
              key: item
            })
          })

          this.setState({
            keyList: keyList,
            data: data,
            columns: columns,
            loading: false
          })
        } else {
          this.setState({
            keyList: [],
            data: [],
            columns: [],
            loading: false
          })
        }

      } else {
        this.setState({
          keyList: [],
          data: [],
          columns: [],
          loading: false
        })
      }
    }, () => {
    })
  }

  // 导出excel
  handelExport = async () => {
    let keyList = this.state.keyList
    let dataList = this.state.data

    if (dataList == null || dataList.length == 0) {
      message.error('Please query the data first!')
      return
    }

    this.setState({
      buttonHidden: true
    })


    let newList = []
    newList.push(keyList)

    for (let i = 0; i < dataList.length; i++) {
      let item = dataList[i]
      let arrTmp = []
      for (let j = 0; j < keyList.length; j++) {
        let key = keyList[j];
        let val = item[key]
        if (typeof val == 'undefined' || val == null) {
          val = ''
        }
        arrTmp.push(val)
      }
      newList.push(arrTmp)
    }

    await this.exportExcel(newList)

    this.setState({
      buttonHidden: false
    })
  }

// 将一个sheet转成最终的excel文件的blob对象，然后利用URL.createObjectURL下载
  sheet2blob(sheet, sheetName) {
    sheetName = sheetName || 'sheet1'
    var workbook = {
      SheetNames: [sheetName],
      Sheets: {}
    }
    workbook.Sheets[sheetName] = sheet;
    // 生成excel的配置项
    var wopts = {
      bookType: 'xlsx', // 要生成的文件类型
      bookSST: false, // 是否生成Shared String Table，官方解释是，如果开启生成速度会下降，但在低版本IOS设备上有更好的兼容性
      type: 'binary'
    }
    var wbout = XLSX.write(workbook, wopts)
    var blob = new Blob([s2ab(wbout)], {type: "application/octet-stream"})

    // 字符串转ArrayBuffer
    function s2ab(s) {
      var buf = new ArrayBuffer(s.length)
      var view = new Uint8Array(buf)
      for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF
      return buf
    }

    return blob;
  }

  /**
   * 通用的打开下载对话框方法，没有测试过具体兼容性
   * @param url 下载地址，也可以是一个blob对象，必选
   * @param saveName 保存文件名，可选
   */
  openDownloadDialog(url, saveName) {
    if (typeof url == 'object' && url instanceof Blob) {
      url = URL.createObjectURL(url) // 创建blob地址
    }
    var aLink = document.createElement('a')
    aLink.href = url
    aLink.download = saveName || '' // HTML5新增的属性，指定保存文件名，可以不要后缀，注意，file:///模式下不会生效
    var event
    if (window.MouseEvent) event = new MouseEvent('click')
    else {
      event = document.createEvent('MouseEvents')
      event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null)
    }
    aLink.dispatchEvent(event)
  }

  // 传入jsonArray 执行后就会弹出下载框
  exportExcel(arrayOfArrays, fileName) {
    var sheet = XLSX.utils.aoa_to_sheet(arrayOfArrays)
    var blob = this.sheet2blob(sheet)
    this.openDownloadDialog(blob, fileName ? fileName : 'data.xlsx')
  }

  render() {
    return (
      <div>

        {
          this.state.exportAllow ?
            <div>
              <Button type="primary" disabled={this.state.buttonHidden} onClick={this.handelExport}>Export</Button>
            </div>
            : null
        }

        <div className="mt20">
          <Table
            pagination={false}
            bordereds
            size='small'
            dataSource={this.state.data}
            columns={this.state.columns}
            title={() => this.state.name}
            loading={this.state.loading}
          />
        </div>
      </div>
    )
  }
}

const WrappedTimeRelatedForm = Form.create()(ReportCommon)

export default WrappedTimeRelatedForm

